# -*- coding: utf-8 -*-
import hashlib
import json
import random
import time
from collections import OrderedDict

import requests
from django.conf import settings

from async import async_job
from common.cache import redis_cache
from common.order import db as order_db
from common.order.model import PAY_STATUS
from common.utils import track_logging
from common.utils.exceptions import ParamError

_LOGGER = track_logging.getLogger(__name__)

_GATEWAY = 'http://106.15.82.115/cnpPay/initPay'
_QUERY_GATEWAY = 'http://106.15.82.115/query/singleOrder'

APP_CONF = {
    'deff87958dfe4bd784509ca25d3084a6': {
        'API_KEY': 'a27dbf4666c84496b0f07039fba7c181',
        'gateway': 'http://106.15.82.115/cnpPay/initPay',
        'query_gateway': 'http://106.15.82.115/query/singleOrder',
    },
    'd8c15f5c691c447785b00884a974f2d5': {  # 金好
        'API_KEY': 'd84389c5e48f44aeb176da65cb96e9b9',
        # 'gateway': 'http://gateway.tfhmye.top/b2cPay/initPay',
        'gateway': 'http://gateway.tfhmye.top/cnpPay/initPay',
        'query_gateway': 'http://gateway.tfhmye.top/query/singleOrder',
    },
    'ffb2ac03749047d09c6c875fd3aec3f8': {
        'API_KEY': '3dbf29597bdd4dd4a93b01338e0f8092',
        'gateway': 'http://106.15.82.115/cnpPay/initPay',
        'query_gateway': 'http://106.15.82.115/query/singleOrder',
    },
    'a53b303f41534d02a31187c0ae6cf828': {
        'API_KEY': 'dd9c31fe26ef44c1b8eca40cb58dcad6',
        'gateway': 'http://106.15.82.115/cnpPay/initPay',
        'query_gateway': 'http://106.15.82.115/query/singleOrder',
    },
    '44539f264524410ab7e98765e7e30f8b': {
        'API_KEY': 'b822f2d3a0f04bfb8008b30d75277b55',
        'gateway': 'http://106.15.82.115/cnpPay/initPay',
        'query_gateway': 'http://106.15.82.115/query/singleOrder',
    },
    '6751aaa647cf4276a1d4c49926516f2c': {  # 合川区风声水喜餐饮店（P）(商户编号:88882018021010001213),
        'API_KEY': 'f95ea1dd8db941fbbaa7e63c0d0666bc',
        'gateway': 'http://106.15.82.115/cnpPay/initPay',
        'query_gateway': 'http://106.15.82.115/query/singleOrder',
    },
    'c72cce97688a46d9b7718fc0df4f4003': {  # witch	讯游通	qq钱包，微信h5
        'API_KEY': '359414e3e76e4de6af37d49d8085b910',
        'gateway': 'https://gateway.ioo8.com/scanPay/initPay',
        'query_gateway': 'https://gateway.ioo8.com/query/singleOrder',
    },
    '2082f036bd954ea199704fd7e0c8d1d1': {  # 金好 witch
        'API_KEY': '2d6b5a3d8dbc491abfa25c64bd5254dc',
        'gateway': 'http://gateway.tfhmye.top/cnpPay/initPay',
        'query_gateway': 'http://gateway.tfhmye.top/query/singleOrder',
    },
    '06c70abc7460406e9a1b9e1c839c91c0': {
        # witch	讯游通	微信3.5%，1---1000。支付宝3.5%，1---2000.都是t1结算。qqwap1.5%，1---1500.京东1.5%，1---5000.d0结算。
        'API_KEY': 'af1089ce01ed44129429e122d944395a',
        'gateway': 'https://gateway.ioo8.com/scanPay/initPay',
        'query_gateway': 'https://gateway.ioo8.com/query/singleOrder',
    },
    'd97f16943ded4454808802320e6d0a11': {
        # witch	g米 支付方式，费率，单笔限额：微信3.5%单笔限额是100-900（整百的充值）t1结算。支付宝3.5%（1---500），qq1.5%（1---1500），
        # 快捷1.5%（1---1w).d0结算。
        'API_KEY': 'e8fc66c71781405caa1b15e576a9aef3',
        'gateway': 'https://gateway.gimi321.com/scanPay/initPay',
        'query_gateway': 'https://gateway.gimi321.com/query/singleOrder',
    },
    'bc30348e886243aeafa10749ec25c111': {
        # witch	g米 支付宝3.5%（50，100，150，200，250，300，350，400---5000）。微信3.5%（100，200，300，400---1000
        # 0）这样的单笔限额。京东1.3%（10---5000），qq1.8%（10---500）
        'API_KEY': '5a4c553467144806b4d3b54909c3b53e',
        'gateway': 'https://gateway.gimi321.com/scanPay/initPay',
        'query_gateway': 'https://gateway.gimi321.com/query/singleOrder',
    },
    'bbed9c54fdec4f409d3e082fec20e644': {  # zs 收付宝 支付宝3.5%（50---3000），qq1.5%(30---1000),都是t0结算。
        'API_KEY': 'dbc945711e894300b5a07c3c9a904123',
        'gateway': 'https://gateway.gaogby.com/scanPay/initPay',
        'query_gateway': 'https://gateway.gaogby.com/query/singleOrder',
    },
    'aeb2f09a14e947ba8a5c1d6ea7967636': {  # loki 快付宝 支付宝3.2%（10---5000）
        'API_KEY': '966d9d6140394c458dfef5994a6c83f8',
        'gateway': 'https://gateway.kzgou.cn/scanPay/initPay',
        'query_gateway': 'https://gateway.kzgou.cn/query/singleOrder',
    },
}


def _get_api_key(mch_id):
    return APP_CONF[mch_id]['API_KEY']


def _get_gateway(mch_id):
    return APP_CONF[mch_id]['gateway']


def _get_query_gateway(mch_id):
    return APP_CONF[mch_id]['query_gateway']


def _get_pay_type(service):
    if service == 'alipay':
        return '20000201'
    elif service == 'alipay1':
        return '20000203'
    elif service == 'wxpay':
        return '10000201'
    elif service == 'wxpay1':
        return '10000203'
    elif service == 'qq':
        return '70000203'
    elif service == 'qq1':
        return '70000103'
    elif service == 'jd':
        return '80000203'
    elif service == 'quick':
        return '40000103'
    elif service == 'quick1':
        return '60000103'
    else:
        return '70000203'


def generate_sign(parameter, key):
    '''  生成下单签名 '''
    s = ''
    for k in sorted(parameter.keys()):
        if parameter[k] != '' and parameter[k] != None:
            s += '%s=%s&' % (k, parameter[k])
    s += 'paySecret=%s' % key
    # _LOGGER.info("juchengpay sign str : %s", s)
    m = hashlib.md5()
    m.update(s.encode('utf8'))
    sign = m.hexdigest().upper()
    return sign


def gen_post_str(parameter):
    sign = parameter['sign']
    parameter.pop('sign')
    s = ''
    for k in sorted(parameter.keys()):
        if parameter[k] != '' and parameter[k] != None:
            s += '%s=%s&' % (k, parameter[k])
    return s + 'sign=' + sign


def verify_notify_sign(params, key):
    sign = params['sign']
    params.pop('sign')
    calculated_sign = generate_sign(params, key)
    if sign != calculated_sign:
        _LOGGER.info("juchengpay sign: %s, calculated sign: %s", sign, calculated_sign)
        raise ParamError('sign not pass, data: %s' % params)


def _get_device_ip(info):
    try:
        extra = json.loads(info['extra'])
    except:
        extra = {}
    user_info = extra.get('user_info', {})
    return user_info.get('device_ip') or '127.0.0.1'


def _build_form(params, gateway):
    html = u"<head><title>loading...</title></head><form id='submit' name='submit' action='" + gateway + "' method='post'>"
    for k, v in params.items():
        html += "<input type='hidden' name='%s' value='%s'/>" % (k, v)
    html += "</form>"
    html += "<script>doc" \
            "ument.forms['submit'].submit();</script>"
    return html


def _fix_pay_amount(pay, pay_amount):
    extend = json.loads(pay.extend or '{}')
    if pay_amount >= 10 and int(pay_amount) == pay_amount:
        discount = random.randint(1, 10)
        pay_amount = pay_amount - float(discount) / 100
        extend.update({'discount': str(float(discount) / 100)})
        order_db.fill_extend(pay.id, extend)
    return pay_amount


def create_charge(pay, pay_amount, info):
    ''' 创建订单 '''
    app_id = info['app_id']
    api_key = _get_api_key(app_id)
    service = info.get('service')
    if service == 'alipay':
        pay_amount = _fix_pay_amount(pay, pay_amount)
    parameter_dict = OrderedDict((
        ('payKey', app_id),
        ('orderPrice', '%.2f' % pay_amount),
        ('outTradeNo', str(pay.id)),
        ('productType', _get_pay_type(service)),
        ('orderTime', time.strftime("%Y%m%d%H%M%S", time.localtime())),
        ('productName', 'charge'),
        ('orderIp', _get_device_ip(info)),
        ('returnUrl', '{}/pay/api/{}/juchengpay/{}'.format(settings.NOTIFY_PREFIX, settings.RETURN_PATH, app_id)),
        ('notifyUrl', '{}/pay/api/{}/juchengpay/{}'.format(settings.NOTIFY_PREFIX, settings.NOTIFY_PATH, app_id)),
        ('remark', 'charge'),
    ))
    parameter_dict['sign'] = generate_sign(parameter_dict, api_key)
    gateway = _get_gateway(app_id)
    _LOGGER.info("juchengpay create  data: %s, url: %s", parameter_dict, gateway)
    headers = {'Content-Type': 'application/x-www-form-urlencoded'}
    response = requests.post(gateway, data=parameter_dict, headers=headers, timeout=3, verify=False)
    _LOGGER.info("juchengpay create  rsp data: %s, url: %s", response.text, response.url)
    payMessage = json.loads(response.text)['payMessage']
    if payMessage.startswith('http'):
        url = payMessage
    else:
        cache_id = redis_cache.save_html(pay.id, payMessage)
        url = settings.PAY_CACHE_URL + cache_id
    return {'charge_info': url}


# SUCCESS
def check_notify_sign(request, app_id):
    data = dict(request.GET.iteritems())
    api_key = _get_api_key(app_id)
    _LOGGER.info("juchengpay notify data1: %s", data)
    _LOGGER.info("juchengpay notify body: %s", request.body)
    verify_notify_sign(data, api_key)
    pay_id = data['outTradeNo']
    if not pay_id:
        _LOGGER.error("fatal error, out_trade_no not exists, data: %s" % data)
        raise ParamError('juchengpay event does not contain pay ID')

    pay = order_db.get_pay(pay_id)
    if not pay:
        raise ParamError('pay_id: %s invalid' % pay_id)
    if pay.status != PAY_STATUS.READY:
        raise ParamError('pay %s has been processed' % pay_id)

    mch_id = pay.mch_id
    trade_status = str(data['tradeStatus'])
    trade_no = data['trxNo']
    total_fee = float(data['orderPrice'])

    discount = float(json.loads(pay.extend or '{}').get('discount', 0))
    extend = {
        'discount': discount,
        'trade_status': trade_status,
        'trade_no': trade_no,
        'total_fee': total_fee
    }

    from common.channel.pay import check_channel_order
    check_channel_order(pay_id, total_fee, app_id)
    if trade_status == 'SUCCESS' or trade_status == 'FINISH':
        _LOGGER.info('juchengpay check order success, mch_id:%s pay_id:%s' % (mch_id, pay_id))
        order_db.add_pay_success(mch_id, pay_id, total_fee, trade_no, extend)
        # async notify
        async_job.notify_mch(pay_id)


def query_charge(pay_order, app_id):
    ''' 查询订单 '''
    # prepare param
    pay_id = pay_order.id
    api_key = _get_api_key(app_id)
    parameter_dict = OrderedDict((
        ('payKey', app_id),
        ('outTradeNo', str(pay_id)),
    ))
    parameter_dict['sign'] = generate_sign(parameter_dict, api_key)
    _LOGGER.info("juchengpay query  data: %s", parameter_dict)
    headers = {'Content-Type': 'application/x-www-form-urlencoded'}
    response = requests.post(_get_query_gateway(app_id), data=parameter_dict, headers=headers, timeout=3, verify=False)
    _LOGGER.info("juchengpay query  rsp data: %s", response.text)
    if response.status_code == 200:
        data = json.loads(response.text)
        trade_status = str(data['orderStatus'])
        trade_no = data['trxNo']
        total_fee = float(data['orderPrice'])
        discount = float(json.loads(pay_order.extend or '{}').get('discount', 0))

        extend = {
            'discount': discount,
            'trade_status': trade_status,
            'trade_no': trade_no,
            'total_fee': total_fee
        }

        if trade_status == 'SUCCESS' or trade_status == 'FINISH':
            _LOGGER.info('juchengpay query order success, user_id:%s pay_id:%s' % (pay_order.mch_id, pay_id))
            order_db.add_pay_success(pay_order.mch_id, pay_order.id,
                                     total_fee, trade_no, extend)
            async_job.notify_mch(pay_order.id)
    else:
        _LOGGER.warn('juchengpay data error, status_code: %s', response.status_code)
